// +FHDR------------------------------------------------------------
//                 Copyright (c) 2022 .
//                       ALL RIGHTS RESERVED
// -----------------------------------------------------------------
// Filename      : apb_adapter.sv
// Author        : 
// Created On    : 2022-08-25 17:34
// Last Modified : 
// -----------------------------------------------------------------
// Description:
//
//
// -FHDR------------------------------------------------------------

`ifndef __APB_ADAPTER_SV__
`define __APB_ADAPTER_SV__

class apb_adapter extends uvm_reg_adapter;
    `uvm_object_utils(apb_adapter)
	
	extern function new(string name = "apb_adapter");
    extern virtual function uvm_sequence_item reg2bus(const ref uvm_reg_bus_op rw);
    extern virtual function void bus2reg(uvm_sequence_item bus_item, ref uvm_reg_bus_op rw);

endclass

function apb_adapter::new(string name = "apb_adapter");
	super.new(name);
    provides_responses = 1;
endfunction: new

function uvm_sequence_item apb_adapter::reg2bus(const ref uvm_reg_bus_op rw);
    apb_transaction apb;
    `uvm_warning("apb_adapter", "call reg2bus!")
    apb = apb_transaction::type_id::create("apb_trans");
    apb.kind = (rw.kind == UVM_READ) ? apb_transaction::READ : apb_transaction::WRITE;
    apb.addr = rw.addr;
    apb.data = rw.data;
    `uvm_warning("apb_adapter", "call reg2bus over!")
    return apb;
endfunction : reg2bus

function void apb_adapter::bus2reg(uvm_sequence_item bus_item, ref uvm_reg_bus_op rw);
    apb_transaction apb;
    if(!$cast(apb, bus_item)) begin
        `uvm_fatal("NO APB TYPE","Provided bus_item is not of the correct type!")
        return;
    end
    `uvm_warning("apb_adapter", "call bus2reg!")
    rw.kind = (apb.kind == apb_transaction::READ) ? UVM_READ : UVM_WRITE;
    rw.addr = apb.addr;
    rw.data = apb.data;
    rw.status = UVM_IS_OK;
    `uvm_warning("apb_adapter", $sformatf("bus2reg get addr = 'h%0h", rw.addr));
endfunction : bus2reg

`endif
